
#IPs ohome:
#router: 192.168.redacted.redacted
#lcompaq: 192.168.redacted.redacted
#local bcast: 192.168.redacted.255
#local net: 192.168.redacted.0/24

#Test if your modifications are syntax ok with: sudo iptables-restore -t $0
#where $0 is this file.

#originally from src: https://www.digitalocean.com/community/tutorials/how-to-implement-a-basic-firewall-template-with-iptables-on-ubuntu-14-04
#now modified

*filter
# Allow all outgoing, but drop incoming and forwarding packets by default
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]

# Custom per-protocol chains
:newUDPin - [0:0]
:newTCPin - [0:0]
:newICMPin - [0:0]
:newUDPout - [0:0]
:newTCPout - [0:0]
:newICMPout - [0:0]

:accepted - [0:0]
:rejected - [0:0]
:rejectwithreset - [0:0]
:dropped - [0:0]
:snh - [0:0]
#snh=should not happen - if it did then there's a bug in the way rules were set up!

#---------------------
# Acceptable newUDPin traffic
#allow qtox:
-A newUDPin -p udp --sport 33445 --dport 33445 -d 255.255.255.255,192.168.redacted.255  -j accepted
-A newUDPin -p udp --sport 33445 --dport 33445 -j accepted
#^ eg. bcast packets from qtoxes running on local LAN machines
#XXX ^ looks like we got some with different sports! [ 5650.616511] rejected:IN=enp1s0 OUT= ... SRC=45.55.232.1 DST=192.168.me LEN=141 TOS=0x00 PREC=0x20 TTL=53 ID=23501 DF PROTO=UDP SPT=33446 DPT=33445 LEN=121   UNSURE YET IF THIS IS NEEDED!
#
#XXX: not really needed:
-A newUDPin -j rejected
#^ so not specifying this means it will still fall through to rejected but it's easier to see if anything got rejected in this category

#---------------------
# Acceptable newUDPout traffic
-A newUDPout -p udp --dport 53 --dst 8.8.4.4,8.8.8.8,208.67.222.220 -j accepted
#allow QUIC (youtube/google) for extra speeds:
#UDP out 443 is QUIC src: http://kb.fortinet.com/kb/documentLink.do?externalID=FD36680
#looks like only 443 out and not 80 out, UDP is seen by my logs
-A newUDPout -p udp --dport 443 -j accepted
#allow qtox:
-A newUDPout -p udp --sport 33445 -j accepted
#allow ntpdate
-A newUDPout -p udp --sport 123 --dport 123 -j accepted
#XXX: not really needed:
-A newUDPout -j rejected
#^ so not specifying this means it will still fall through to rejected but it's easier to see if anything got rejected in this category

#---------------------
# Acceptable incoming newTCPin traffic
#-A newTCPin -p tcp --dport 22 -j accepted
#redundant: -A newTCPin -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW -j accepted
#incoming distcc so they can compile on my machine
#-A newTCPout -p tcp -s 192.168.redacted.0/24 --dport 3632 -j accepted
#XXX: not really needed:
-A newTCPin -j rejected

#TODO: 
#distcc on other machines
#-A newTCPout -p tcp -d 192.168.redacted.0/24 --dport 3632 -j accepted
#ftp:
#-A newTCPout -p tcp --dport 21 -j accepted
#21=ftp 11371=keyserver
#-A newTCPout -p tcp -m multiport --dports 21,11371 -j accepted
-A newTCPout -p tcp -m multiport --dports 80,443 -j accepted
-A newTCPout -p tcp -m multiport --dports 802,46802 -j accepted
-A newTCPout -p tcp --dport 22 -m hashlimit --hashlimit-name ssh_dest --hashlimit-mode dstip --hashlimit-upto 30/minute -j accepted
#^ doc: http://ipset.netfilter.org/iptables-extensions.man.html
# also in: man iptables-extensions
-A newTCPout -p tcp --dport 23 -d 192.168.redacted.redacted -m hashlimit --hashlimit-name ssh_dest --hashlimit-mode dstip --hashlimit-upto 30/minute -j accepted
#qtox:
-A newTCPout -p tcp --dport 33445 -j accepted
#
#plaintext git (eg. from pacman source=git:// or git+git:// eg. gstreamer-git package) 
-A newTCPout -p tcp --dport 9418 -j accepted

#vnc to lcompaq
-A newTCPout -p tcp --dport 5900 -d 192.168.redacted.redacted -m hashlimit --hashlimit-name ssh_dest --hashlimit-mode dstip --hashlimit-upto 30/minute -j accepted
#XXX: not really needed:
-A newTCPout -j rejected

#------------------ common ICMP blocks
:commonICMPblocks - [0:0]
#block deprecated ICMPs
#Some ICMP types are deprecated, so they should probably be blocked unconditionally. Among these are ICMP source quench (type 4 code 0) and alternate host (type 6). Types 1, 2, 7 and type 15 and above are all deprecated, reserved for future use, or experimental.
-A commonICMPblocks -p icmp --icmp-type 4/0 -j dropped
-A commonICMPblocks -p icmp --icmp-type 6 -j dropped
-A commonICMPblocks -p icmp --icmp-type 1 -j dropped
-A commonICMPblocks -p icmp --icmp-type 2 -j dropped
-A commonICMPblocks -p icmp --icmp-type 7 -j dropped
-A commonICMPblocks -p icmp --icmp-type 15 -j dropped
-A commonICMPblocks -p icmp --icmp-type 16 -j dropped
#Next:
#src: src: https://www.digitalocean.com/community/tutorials/how-to-choose-an-effective-firewall-policy-to-secure-your-servers
#block ICMP redirect messages (type 5)
-A commonICMPblocks -p icmp --icmp-type 5 -j dropped
#block ICMP router advertisement (type 9) and router solicitation (type 10) packets. - they require redirect(type 5) to work anyway.
-A commonICMPblocks -p icmp --icmp-type 9 -j dropped
-A commonICMPblocks -p icmp --icmp-type 10 -j dropped
#block ICMP type 13 - timestamp request
-A commonICMPblocks -p icmp --icmp-type 13 -j dropped
#--------------------- new ICMP in

# Acceptable newICMPin traffic
-A newICMPin -j commonICMPblocks
#-A newICMPin -j rejected
#FIXME: allow local IPs to ping me?
#XXX: echo-request looks like type 8 code 0, assuming code != 0 is N/A
#-A newICMPin -p icmp --icmp-type echo-request -j dropped
-A newICMPin -p icmp --icmp-type 8/0 -j dropped
#this can't be here in the NEW state!(only esta/related): -A newICMPin -p icmp --icmp-type echo-reply -j accepted
# ^ doc: iptables -p icmp -h   AND man iptables-extensions
#FIXME: do I need to allow related icmp traffic here? or is it handled already? apparently handled - not tested!

#-------------- new ICMP out
-A newICMPout -j commonICMPblocks
#-A newICMPout -p icmp --icmp-type echo-request -m hashlimit --hashlimit-name ping_dest --hashlimit-mode dstip --hashlimit-upto 2/second -m connlimit --connlimit-upto 2 --connlimit-daddr --connlimit-mask 32 -j accepted
-A newICMPout -p icmp --icmp-type 8/0 -m hashlimit --hashlimit-name ping_dest --hashlimit-mode dstip --hashlimit-upto 2/second -m connlimit --connlimit-upto 65 --connlimit-daddr --connlimit-mask 32 -j accepted
#XXX: changed connlimit-upto to 65 from 2, because if I ping an IP then C-c, the third time it will fail until like 30 sec pass or something like that! - probably conntrack keeps them open for 30 sec after ping exited so they get counted like that!
#Do I need to allow anything in the NEW icmp here? or do they fall into RELATED?

#--------- established/related ICMP incoming
#descriptions src: https://www.digitalocean.com/community/tutorials/how-to-choose-an-effective-firewall-policy-to-secure-your-servers
:estaICMPin - [0:0]
#Type 0 — Echo replies: These are responses to echo requests (pings).
#XXX: looks like type 0 code 0 is the reply, assuming code != 0 is N/A
#-A estaICMPin -p icmp --icmp-type echo-reply -j accepted
-A estaICMPin -p icmp --icmp-type 0/0 -j accepted
#Type 3 — Destination Unreachable: Legitimate destination unreachable packets are responses to requests created by your server indicating that the packet could not be delivered.
-A estaICMPin -p icmp --icmp-type 3 -j accepted
#Type 11 — Time exceeded: This is a diagnostic error returned if a packet generated by your server died before reaching the destination because of exceeding its TTL value.
-A estaICMPin -p icmp --icmp-type 11 -j accepted
#Type 12 — Parameter problem: This means that an outgoing packet from your server was malformed.
-A estaICMPin -p icmp --icmp-type 12 -j accepted
#Type 14 — Timestamp responses: These are the responses for timestamp queries generated by your server. FIXME: wuuuut?
-A estaICMPin -p icmp --icmp-type 14 -j accepted
#others are not allowed... will fall back to rejected on return somewhere in INPUT
#-----------

-A snh -j LOG --log-prefix "snh:" --log-level 4 --log-uid
-A snh -j rejected

#XXX: do not log the accepted:
#-A accepted -j LOG --log-prefix "accepted:" --log-level 7 --log-uid
-A accepted -j ACCEPT


#XXX: do not log these qTox broadcasted LAN packets
#-A rejected -p udp --sport 33445 --dport 33445 -d 255.255.255.255,192.168.redacted.255  -m limit --limit 700/minute --limit-burst 2 -j rejectwithreset
#should be 720/hour but I do want to log some of them.
#syslog levels (--log-level): https://en.wikipedia.org/wiki/Syslog#Severity_level
#--log-uid Log the userid of the process which generated the packet.
-A rejected -j LOG --log-prefix "rejected:" --log-level 6 --log-uid
-A rejected -j rejectwithreset

## Try to be protocol-specific w/ rejection message
#TODO: log each type of the 3 below, separately! (maybe it's not needed?)
-A rejectwithreset -p tcp -j REJECT --reject-with tcp-reset
-A rejectwithreset -p udp -j REJECT --reject-with icmp-port-unreachable
-A rejectwithreset -j REJECT --reject-with icmp-proto-unreachable

-A dropped -j LOG --log-prefix "dropped:" --log-level 6 --log-uid
-A dropped -j DROP


#---------------INPUT

# Boilerplate acceptance policy for incoming traffic
#-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED ! -p icmp -j accepted
#log less:
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED ! -p icmp -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -p icmp -j estaICMPin
#ftp: -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT

# Drop invalid packets
-A INPUT -m conntrack --ctstate INVALID -j dropped

#127.0.0.3/32 is hostBlocked  it's in /etc/hosts !
#127.0.0.1/8 is whole 127.*.*.* network!
#-A INPUT -i lo -s 127.0.0.1/8 -d hostBlocked -j snh
-A INPUT -i lo -s 127.0.0.1/8 -d 127.3.0.0/16 -j snh
#XXX: ^ 127.3.0.0/16 is in accordance with /etc/hosts which is from: /home/z/build/1nonpkgs/hosts/
-A INPUT -i lo -s 127.0.0.1/8 -d 127.0.0.1/8 -m conntrack --ctstate NEW -j accepted
#-A INPUT -i lo -j accepted
#TODO: restrict this lo conntrack-like

# Pass traffic to protocol-specific chains
## Only allow new connections (established and related should already be handled)
## For newTCPin, additionally only allow new SYN packets since that is the only valid
## method for establishing a new newTCPin connection
-A INPUT -p udp -m conntrack --ctstate NEW -j newUDPin
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j newTCPin
-A INPUT -p icmp -m conntrack --ctstate NEW -j newICMPin

# Reject anything that's fallen through to this point
-A INPUT -j rejected


#---------------OUTPUT
#
#----no-internet/emacs stuff
-A OUTPUT -m owner --gid-owner no-internet -j dropped
:emacs - [0:0]
-A OUTPUT -m owner --gid-owner emacs -j emacs
-A emacs -d 104.236.16.183/32 -p tcp -j accepted
-A emacs -d 208.118.235.89/32 -p tcp -j accepted
#melpa.org
##elpa.gnu.org
##XXX: added these to /etc/hosts to ensure they don't change!
-A emacs -j rejected
#-A emacs -j DROP
#----------------

#-A OUTPUT -o lo -j accepted
#-A OUTPUT -o lo -s 127.0.0.1/8 -d hostBlocked -j rejected
-A OUTPUT -o lo -s 127.0.0.1/8 -d 127.3.0.0/16 -j rejected
#XXX: ^ 127.3.0.0/16 is in accordance with /etc/hosts which is from: /home/z/build/1nonpkgs/hosts/
#-A OUTPUT -o lo -s 127.0.0.1/8 -d 127.0.0.1/8 -j accepted
-A OUTPUT -o lo -s 127.0.0.1/8 -d 127.0.0.1/8 -m conntrack --ctstate NEW -j accepted

:estaICMPout - [0:0]
#FIXME: ?
-A estaICMPout -j commonICMPblocks
-A estaICMPout -j accepted

#-A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED ! -p icmp -j accepted
#XXX: log less:
-A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED ! -p icmp -j ACCEPT

-A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -p icmp -j estaICMPout

#ftp passive? https://www.devops-blog.net/iptables/iptables-settings-for-outgoing-ftp
#-A OUTPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j accepted
#FIXME: I might need module: ip_conntrack and ip_conntrack_ftp  loaded!

-A OUTPUT -p udp -m conntrack --ctstate NEW -j newUDPout
-A OUTPUT -p tcp --syn -m conntrack --ctstate NEW -j newTCPout
-A OUTPUT -p icmp -m conntrack --ctstate NEW -j newICMPout
-A OUTPUT -j rejected

# Commit the changes
COMMIT

*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
#incoming: -A PREROUTING -p icmp -j TRACE
#outgoing: -A OUTPUT -p icmp -j TRACE
#-A OUTPUT -p tcp -j TRACE

#XXX: x_tables: ip_tables: REJECT target: only valid in filter table, not nat
#:rejected - [0:0]
##TODO: log each type of the 3 below, separately! (maybe it's not needed?)
#-A rejected -j LOG --log-prefix "rejected:" --log-level 6
#-A rejected -p tcp -j REJECT --reject-with tcp-reset
#-A rejected -p udp -j REJECT --reject-with icmp-port-unreachable
#-A rejected -j REJECT --reject-with icmp-proto-unreachable
#
#-A PREROUTING -j rejected
#-A OUTPUT -j rejected
#
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

##XXX: x_tables: ip_tables: REJECT target: only valid in filter table, not nat
#:rejected - [0:0]
##TODO: log each type of the 3 below, separately! (maybe it's not needed?)
#-A rejected -j LOG --log-prefix "rejected:" --log-level 6
#-A rejected -p tcp -j REJECT --reject-with tcp-reset
#-A rejected -p udp -j REJECT --reject-with icmp-port-unreachable
#-A rejected -j REJECT --reject-with icmp-proto-unreachable
#
#-A PREROUTING -j rejected
#-A INPUT -j rejected
#-A OUTPUT -j rejected
#-A POSTROUTING -j rejected
COMMIT

*security
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

##XXX: x_tables: ip_tables: REJECT target: only valid in filter table, not security
#:rejected - [0:0]
##TODO: log each type of the 3 below, separately! (maybe it's not needed?)
#-A rejected -j LOG --log-prefix "rejected:" --log-level 6
#-A rejected -p tcp -j REJECT --reject-with tcp-reset
#-A rejected -p udp -j REJECT --reject-with icmp-port-unreachable
#-A rejected -j REJECT --reject-with icmp-proto-unreachable

#-A INPUT -j rejected
#-A FORWARD -j rejected
#-A OUTPUT -j rejected
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

##XXX: x_tables: ip_tables: REJECT target: only valid in filter table, not mangle
#:rejected - [0:0]
##TODO: log each type of the 3 below, separately! (maybe it's not needed?)
#-A rejected -j LOG --log-prefix "rejected:" --log-level 6
#-A rejected -p tcp -j REJECT --reject-with tcp-reset
#-A rejected -p udp -j REJECT --reject-with icmp-port-unreachable
#-A rejected -j REJECT --reject-with icmp-proto-unreachable

#-A PREROUTING -j rejected
#-A INPUT -j rejected
#-A FORWARD -j rejected
#-A OUTPUT -j rejected
#-A POSTROUTING -j rejected
COMMIT

